/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Expressoes;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.Regras.Tipos.RegraTipoPrimitivo;
import java.util.LinkedList;

/**
 *
 * @author matheus
 * nathy
 */
public class RegraCast extends Regra {

    protected static Regra instancia;

    // @Override

    //<cast> ::= <unario_prefixa> | "(" <tipo_primitivo> ")" <cast>
    protected String estrutura = "<unario_prefixa> | '(' <tipo_primitivo> ')' <cast>";
    

    /**
     * Construtor privado necessario ao singleton
     */
    private RegraCast() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraCast getInstance() {
        if (instancia == null) {
            instancia = new RegraCast();
        }
        return (RegraCast) instancia;
    }

    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

        TiposSemanticos tipoReturn = new TiposSemanticos();

        if ("(".equals(listaTokens.getFirst().getLexema()) && listaContem(RegraTipoPrimitivo.getInstance().getPrimeiro(), listaTokens.get(1))) {//lista de tokens que vem do analisador sintático

            reconheceLexema(listaTokens, "delimitador", "(", estrutura);
            

             TiposSemanticos tipoCast = RegraTipoPrimitivo.getInstance().analisar(listaTokens);
             if(tipoCast == null){
                 tipoReturn =  null;
             }else{
                //O tipo vai ser o primitivo retornado pelo cast
                tipoReturn.addTipos(tipoCast.getFirst());
             }

            

              reconheceLexema(listaTokens, "delimitador", ")", estrutura);


              TiposSemanticos tipo2 = RegraCast.getInstance().analisar(listaTokens);
              if(tipo2 == null){
                 tipoReturn =  null;
             }

        }else{
                tipoReturn = RegraUnarioPrefixa.getInstance().analisar(listaTokens);;
        }
        
        return tipoReturn;
    }

    protected void setPrimeiro() {
        primeiro.add("(");
        primeiro = getUniao(primeiro, RegraUnarioPrefixa.getInstance().getPrimeiro());
    }
}
